package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sky.dto.WxLoginDTO;
import com.sky.dto.WxPhoneDTO;
import com.sky.entity.User;
import com.sky.entity.WxUser;
import com.sky.mapper.UserMapper;
import com.sky.mapper.WxUserMapper;
import com.sky.properties.JwtProperties;
import com.sky.properties.WeChatProperties;
import com.sky.result.Result;
import com.sky.service.WxUserService;
import com.sky.utils.JwtUtil;
import com.sky.utils.WechatUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.sky.properties.WeChatProperties;
import com.sky.dto.ProposalDTO;
import com.sky.entity.Proposal;
import com.sky.mapper.ProposalMapper;
import org.apache.commons.lang.StringUtils;

@Service
@Slf4j
public class WxUserServiceImpl implements WxUserService {

    @Autowired
    private WeChatProperties wechatProperties;
    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private WxUserMapper wxUserMapper;
    @Autowired
    private UserMapper userMapper;  // 添加 UserMapper
    @Autowired
    private RestTemplate restTemplate;

    // 添加基础的CRUD方法实现
    @Override
    public WxUser findByOpenid(String openid) {
        return wxUserMapper.findByOpenid(openid);
    }

    @Override
    public void save(WxUser wxUser) {
        wxUserMapper.insert(wxUser);
    }

    @Override
    public void update(WxUser wxUser) {
        wxUserMapper.update(wxUser);
    }

    // 原有的登录方法保持不变
    @Override
    public Result<Object> wxLogin(WxLoginDTO loginDTO) {
        try {
            log.info("收到微信登录请求，code: {}, userInfo: {}", loginDTO.getCode(), loginDTO.getUserInfo());
            
            // 验证输入参数
            if (loginDTO.getCode() == null || loginDTO.getCode().isEmpty()) {
                log.error("登录失败：code为空");
                return Result.error("登录失败：code不能为空");
            }

            // 验证配置信息
            if (wechatProperties.getMiniapp() == null 
                || wechatProperties.getMiniapp().getAppid() == null 
                || wechatProperties.getMiniapp().getSecret() == null) {
                log.error("微信小程序配置错误：{}", wechatProperties.getMiniapp());
                return Result.error("系统配置错误");
            }

            // 打印完整的配置信息
            log.info("微信小程序配置信息：appid={}, login-url={}", 
                    wechatProperties.getMiniapp().getAppid(),
                    wechatProperties.getMiniapp().getLoginUrl());
            
            // 构建请求URL
            String url = wechatProperties.getMiniapp().getLoginUrl() +
                    "?appid=" + wechatProperties.getMiniapp().getAppid() +
                    "&secret=" + wechatProperties.getMiniapp().getSecret() +
                    "&js_code=" + loginDTO.getCode() +
                    "&grant_type=authorization_code";
            
            // 发送请求前打印完整URL（注意隐藏secret）
            String logUrl = url.replaceAll(wechatProperties.getMiniapp().getSecret(), "****");
            log.info("请求微信登录接口URL: {}", logUrl);
            
            // 发送请求并记录响应
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
            log.info("微信接口响应状态码：{}", response.getStatusCodeValue());
            log.info("微信接口响应头：{}", response.getHeaders());
            log.info("微信接口响应体：{}", response.getBody());
            
            JSONObject jsonObject = JSON.parseObject(response.getBody());
            
            // 检查错误码
            Integer errcode = jsonObject.getInteger("errcode");
            if (errcode != null) {
                log.error("微信登录失败，错误码：{}，错误信息：{}", 
                        errcode, jsonObject.getString("errmsg"));
                return Result.error("微信登录失败：" + jsonObject.getString("errmsg"));
            }
        
            String openid = jsonObject.getString("openid");
            String sessionKey = jsonObject.getString("session_key");
            
            if (openid == null || sessionKey == null) {
                return Result.error("微信登录失败");
            }
        
            // 2. 查询用户是否存在
            WxUser wxUser = wxUserMapper.findByOpenid(openid);
            
            // 3. 用户不存在则创建新用户
            if (wxUser == null) {
                // 创建微信用户
                wxUser = new WxUser();
                BeanUtils.copyProperties(loginDTO.getUserInfo(), wxUser);
                wxUser.setOpenid(openid);
                wxUser.setSessionKey(sessionKey);
                wxUser.setCreateTime(LocalDateTime.now());
                wxUserMapper.insert(wxUser);  // 这里会自动设置 wxUser 的 id
            
                // 同时创建用户表记录，使用相同的 id
                User user = new User();
                user.setId(wxUser.getId());  // 设置相同的 id
                user.setOpenid(openid);
                user.setNickname(wxUser.getNickName());
                user.setPhone(wxUser.getPhone());
                user.setGender(wxUser.getGender());
                user.setAvatarUrl(wxUser.getAvatarUrl());
                user.setCreateTime(LocalDateTime.now());
                user.setUpdateTime(LocalDateTime.now());
                user.setCountry(wxUser.getCountry());
                user.setCity(wxUser.getCity());
                user.setLanguage(wxUser.getLanguage());
                user.setProvince(wxUser.getProvince());
                userMapper.insert(user);
            }
        
            // 4. 用户存在则更新信息
            BeanUtils.copyProperties(loginDTO.getUserInfo(), wxUser);
            wxUser.setSessionKey(sessionKey);
            wxUserMapper.update(wxUser);

            // 同时更新用户表
            User user = userMapper.getByOpenid(openid);
            if (user != null) {
                user.setNickname(wxUser.getNickName());
                user.setPhone(wxUser.getPhone());
                user.setGender(wxUser.getGender());
                user.setAvatarUrl(wxUser.getAvatarUrl());
                user.setUpdateTime(LocalDateTime.now());
                user.setCountry(wxUser.getCountry());
                user.setCity(wxUser.getCity());
                user.setLanguage(wxUser.getLanguage());
                user.setProvince(wxUser.getProvince());
                userMapper.update(user);
            }
        
            // 5. 生成token
            Map<String, Object> claims = new HashMap<>();
            claims.put("userId", wxUser.getId());
            claims.put("openid", openid);
            String token = JwtUtil.createJWT(
                    jwtProperties.getUserSecretKey(),
                    jwtProperties.getUserTtl(),
                    claims);
        
            // 6. 构建返回数据
            // 修改返回数据结构
            Map<String, Object> result = new HashMap<>();
            result.put("token", token);
            result.put("id", wxUser.getId());
            result.put("nickName", wxUser.getNickName());
            result.put("avatarUrl", wxUser.getAvatarUrl());
            result.put("openid", openid);  // 添加 openid
            
            return Result.success(result);
        } catch (Exception e) {
            log.error("微信登录异常", e);
            return Result.error("登录失败：" + e.getMessage());
        }
    }

    @Override
    public Result<Object> bindPhone(WxPhoneDTO wxPhoneDTO, String token) {
        try {
            // 1. 解析token获取用户信息
            Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token);
            String openid = claims.get("openid", String.class);
            
            // 2. 查询用户
            WxUser wxUser = wxUserMapper.findByOpenid(openid);
            if (wxUser == null) {
                return Result.error("用户不存在");
            }
            
            // 3. 解密手机号
            String sessionKey = wxUser.getSessionKey();
            String encryptedData = wxPhoneDTO.getEncryptedData();
            String iv = wxPhoneDTO.getIv();
            
            // 使用微信提供的解密算法解密手机号
            String result = WechatUtil.decryptPhone(encryptedData, sessionKey, iv);
            JSONObject jsonObject = JSON.parseObject(result);
            String phone = jsonObject.getString("phoneNumber");
            
            // 4. 更新微信用户手机号
            wxUser.setPhone(phone);
            wxUserMapper.update(wxUser);
            
            // 5. 同时更新user表中的手机号
            User user = userMapper.getByOpenid(openid);
            if (user != null) {
                user.setPhone(phone);
                user.setUpdateTime(LocalDateTime.now());
                userMapper.update(user);
            }
            
            // 6. 构建返回数据
            Map<String, String> data = new HashMap<>();
            data.put("phone", phone);
            
            return Result.success(data);
        } catch (Exception e) {
            log.error("绑定手机号失败", e);
            return Result.error("绑定手机号失败：" + e.getMessage());
        }
    }

    @Autowired
    private ProposalMapper proposalMapper;

    @Override
    public Result<String> submitProposal(ProposalDTO proposalDTO) {
        // 参数校验
        if (StringUtils.isBlank(proposalDTO.getNickName())) {
            return Result.error("微信昵称不能为空");
        }
        if (StringUtils.isBlank(proposalDTO.getPhoneNumber())) {
            return Result.error("手机号不能为空");
        }
        if (StringUtils.isBlank(proposalDTO.getProposalType())) {
            return Result.error("反馈类型不能为空");
        }
        if (StringUtils.isBlank(proposalDTO.getContent())) {
            return Result.error("反馈内容不能为空");
        }

        try {
            // 创建并保存反馈信息
            Proposal proposal = new Proposal();
            BeanUtils.copyProperties(proposalDTO, proposal);
            proposal.setCreateTime(LocalDateTime.now());
            proposal.setUpdateTime(LocalDateTime.now());
            
            proposalMapper.insert(proposal);
            
            return Result.success("反馈提交成功");
        } catch (Exception e) {
            log.error("保存用户反馈信息失败：", e);
            return Result.error("反馈提交失败：" + e.getMessage());
        }
    }

    @Override
    public Result<List<Proposal>> getProposalList() {
        try {
            List<Proposal> proposals = proposalMapper.list();
            return Result.success(proposals);
        } catch (Exception e) {
            log.error("获取用户反馈列表失败：", e);
            return Result.error("获取反馈列表失败");
        }
    }

    @Override
    public Result<String> deleteProposal(Long id) {
        try {
            proposalMapper.deleteById(id);
            return Result.success("删除成功");
        } catch (Exception e) {
            log.error("删除用户反馈失败：", e);
            return Result.error("删除失败");
        }
    }
}